#!/usr/bin/env bash
###################
MACHINE_NAME=$(printf "%s\n" "${DEBIAN_FOLDER}" | sed 's@_@-@g') #此处并非重复操作
unset TMOE_SD_DIR
if grep -Eq '^root:(\*|\!):' "${DEBIAN_CHROOT}"/etc/shadow; then
    ${TMOE_CHROOT_PREFIX} sed -i -E 's@(^root):.:@\1::@g' "${DEBIAN_CHROOT}"/etc/shadow
fi
# case $(${TMOE_CHROOT_PREFIX} cat ${DEBIAN_CHROOT}/etc/hostname) in
# localhost | LXC_NAME | "")
#     # ${TMOE_CHROOT_PREFIX} printf "%s\n" "${MACHINE_NAME}" >>${DEBIAN_CHROOT}/etc/hostname
#     # ${TMOE_CHROOT_PREFIX} printf "%s\n" "127.0.0.1       ${MACHINE_NAME}" >>${DEBIAN_CHROOT}/etc/hosts
#     ;;
# esac
printf "%s\n" "${MACHINE_NAME}" >"${TMPDIR}"/.tmp_hostname
${TMOE_CHROOT_PREFIX} cp "${TMPDIR}"/.tmp_hostname "${DEBIAN_CHROOT}"/tmp
${TMOE_CHROOT_PREFIX} mv "${TMPDIR}"/.tmp_hostname "${DEBIAN_CHROOT}"/etc

if [[ -e "${DEBIAN_CHROOT}/etc/machine-id" ]]; then
    ${TMOE_CHROOT_PREFIX} rm -f "${DEBIAN_CHROOT}"/etc/machine-id
fi
TMP_FILE="${TMPDIR}/.TMOE_NSPAWN_STARTUP"
cat >"${TMP_FILE}" <<-ENDOFTMOECHROOT
#!/usr/bin/env bash
#------------------
# If the value is true, then you can run systemctl command in the container. Default is false
# 若为true,则允许在容器内执行systemctl。注：建议以非root用户进行登录。
SYSTEMD_BOOT=false
#------------------
# You can specify a user. Default is root
# 您可以指定用户，例如root或ubuntu，默认为root
# Sie können einen Benutzer angeben
CHROOT_USER=root

# You can specify the path where the binary file of systemd-nspawn is located. If the value is system, it will use the default path of the system. You can also enter the full path. For example, "\${PREFIX}/bin/systemd-nspawn"
# 您可以自行编译systemd-nspawn,并指定其二进制文件所在路径。当此变量值为system时，将使用系统默认systemd-nspawn二进制文件所在路径；当其为prefix时，将使用 "${PREFIX}/bin/systemd-nspawn"。您也可以输入完整路径,例如"/usr/local/bin/systemd-nspawn"
CHROOT_BIN="system"
###################
# mount dirs & dev
# 挂载相关目录 & 设备

# Default is true. 若设备支持，则启用GPU加速
MOUNT_DEV_DRI=true

DEV_DRI="/dev/dri"

MOUNT_NVIDIA_GPU=true
NVIDIA_GPU="/dev/nvidia0"
NVIDIA_CTL="/dev/nvidiactl"

# Default is false.
MOUNT_X11_UNIX=false

# read only.
X11_UNIX_RO=true
X11_UNIX_DIR="/tmp/.x11-unix"

# 挂载sd，默认为true，SD_DIR为宿主机sd目录。优先级别高，且存在相应目录时，才会被挂载。默认挂载点为容器内部的"/media/sd"
MOUNT_SD=true

# The lower the number, the higher the priority. The highest priority directory will be mounted to the "/media/sd".
SD_DIR_0="/media/sd"
SD_DIR_1="${HOME}/sd"
SD_DIR_2="${HOME}/Downloads"
SD_DIR_3="${HOME}/Download"
SD_DIR_4="/sd"
SD_DIR_5="/sdcard"
SD_MOUNT_POINT="/media/sd"

# If the value of "MOUNT_DOCKER_DIR" is "false", the relevant directory will not be mounted. Default is true.
MOUNT_DOCKER_DIR=true
TMOE_DOCKER_DIR="/media/docker"

#---
# uint8
# 默认为12, 若您将该值修改为15, 则请手动添加MOUNT_SOURCE_13,MOUNT_SOURCE_14,MOUNT_SOURCE_15,MOUNT_POINT_13,MOUNT_POINT_14 & MOUNT_POINT_15 变量。
# If you want to mount hundreds of directories, then you need to add variables manually.
NUM_OF_MOUNTS=12
#---
# MOUNT_SOURCE_1为第一个挂载源，MOUNT_POINT_1 为第一个挂载点，MOUNT_SOURCE_2为第二个挂载源 ...
# 举个例子，假如您想将/storage/emulated/0/Download目录挂载至容器内部的/media/down, 那么MOUNT_SOURCE_1的值为"/storage/emulated/0/Download", MOUNT_POINT_1的值为"/media/down"
# 若BIND_RO的值为true,则为只读挂载。默认为false。注：该变量的值可以留空
# For example, if you want to mount the /storage/emulated/0/DCIM directory to /media/pic, then the value of MOUNT_SOURCE_2 is "/storage/emulated/0/DCIM", and the value of MOUNT_POINT_2 is "/media/pic"
# The --bind-ro= option creates read-only bind mounts.
MOUNT_SOURCE_1=""
MOUNT_POINT_1=""
BIND_RO_1=false
#---
MOUNT_SOURCE_2=""
MOUNT_POINT_2=""
BIND_RO_2=false
#---
MOUNT_SOURCE_3=""
MOUNT_POINT_3=""
BIND_RO_3=false
#---
MOUNT_SOURCE_4=""
MOUNT_POINT_4=""
#---
MOUNT_SOURCE_5=""
MOUNT_POINT_5=""
#---
MOUNT_SOURCE_6=""
MOUNT_POINT_6=""
#---
MOUNT_SOURCE_7=""
MOUNT_POINT_7=""
#---
MOUNT_SOURCE_8=""
MOUNT_POINT_8=""
#---
MOUNT_SOURCE_9=""
MOUNT_POINT_9=""
#---
MOUNT_SOURCE_10=""
MOUNT_POINT_10=""
#---
MOUNT_SOURCE_11=""
MOUNT_POINT_11=""
#---
MOUNT_SOURCE_12=""
MOUNT_POINT_12=""
#---
###################
ROOTFS_DIR="${DEBIAN_CHROOT}"
LOAD_ENV_FILE=true

# Load the environment variable file when starting the container. Default is true.
CONTAINER_ENV_FILE="\${ROOTFS_DIR}/usr/local/etc/tmoe-linux/environment/container.env"

# Default is false.
# 默认为false。当该值为true时，当前配置信息将会被配置文件里的内容所覆盖。
LOAD_NSPAWN_CONF=false

NSPAWN_CONF_FILE="${CONFIG_FOLDER}/nspawn_global.conf" 

TMOE_LOCALE_FILE="${CONFIG_FOLDER}/locale.txt"
###################
if [[ \${LOAD_NSPAWN_CONF} = true && -r \${NSPAWN_CONF_FILE} ]]; then
    source \${NSPAWN_CONF_FILE}
fi
unset CONTAINER_BIN_PATH
if [[ \${SYSTEMD_BOOT} = true ]]; then
    set -- "\${@}" "--boot"
fi
if [[ \${CHROOT_USER} != root && \${SYSTEMD_BOOT} != true ]];then
    set -- "\${@}" "--user" "\${CHROOT_USER}"
fi
set -- "\${@}" "--directory" "\${ROOTFS_DIR}"
set -- "\${@}" "--uuid" "$(dbus-uuidgen)"
# if container=arch, then do not set the value of --private-users to pick.
set -- "\${@}" "--private-users=no"
set -- "\${@}" "--machine" "${MACHINE_NAME}"
set -- "\${@}" "--link-journal" "auto"
set -- "\${@}" "--resolv-conf" "auto"
set -- "\${@}" "--timezone" "auto"
set -- "\${@}" "--register" "yes"
set -- "\${@}" "--notify-ready" "yes"
set -- "\${@}" "--setenv" "TMOE_CHROOT=true"
set -- "\${@}" "--setenv" "TMOE_PROOT=false"
set -- "\${@}" "--setenv" "TMOE_DOCKER=false"
set -- "\${@}" "--setenv" "USER=\${CHROOT_USER}"
# set -- "\${@}" "--setenv" "PULSE_SERVER=unix:/usr/lib/systemd/user/pulseaudio.socket"
# set -- "\${@} "--bind-ro" "/usr/lib/systemd/user/pulseaudio.socket"
set -- "\${@}" "--setenv" "PULSE_SERVER=tcp:127.0.0.1:4713"
set -- "\${@}" "--setenv" "DISPLAY=127.0.0.1:0"
set -- "\${@}" "--setenv" "GTK_IM_MODULE=fcitx"
set -- "\${@}" "--setenv" "QT_IM_MODULE=fcitx"
set -- "\${@}" "--setenv" "XMODIFIERS=\@im=fcitx"
set -- "\${@}" "--setenv" "SDL_IM_MODULE=fcitx"
set -- "\${@}" "--setenv" "CONTAINER_SYSTEMD=true"
set -- "\${@}" "--setenv" "TERM=xterm-256color"

if [[ -e "\${TMOE_LOCALE_FILE}" ]]; then
    set -- "\${@}" "--setenv" "LANG=\$(head -n 1 \${TMOE_LOCALE_FILE})"
else
    set -- "\${@}" "--setenv" "LANG=C.UTF-8"
fi

if [[ -s \${CONTAINER_ENV_FILE} && \${LOAD_ENV_FILE} = true ]]; then
    CONTAINER_BIN_PATH=\$(sed -E 's@export\s+@@;/#/d' \${CONTAINER_ENV_FILE} | grep '^PATH=\"' | grep '\${PATH:+:\${PATH}}' | sed 's@\${PATH:+:\${PATH}}\"@:@;s@PATH=\"@@')
    OLD_IFS="\${IFS}"
    IFS=\$'\n'
    CONTAINER_ENV_VAR="\$(sed -E 's@export\s+@@;/#/d;/^PATH=/d' \${CONTAINER_ENV_FILE})"
    # Do not use double quotes in CONTAINER_ENV_VAR in the for statement 
    for i in \${CONTAINER_ENV_VAR}; do
        if [[ -n \${i} ]];then
            set -- "\${@}" "--setenv" "\${i}"
        fi
    done
    IFS="\${OLD_IFS}"    
fi

if [[ \${CHROOT_USER} = root || -z \${CHROOT_USER} ]]; then
	set -- "\${@}" "--setenv" "PATH=\${CONTAINER_BIN_PATH}/usr/local/sbin:/usr/local/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/games:/usr/local/games"
else
	set -- "\${@}" "--setenv" "PATH=\${CONTAINER_BIN_PATH}/usr/local/bin:/bin:/usr/bin:/usr/games:/usr/local/games"
fi

if [[ \${MOUNT_SD} = true ]]; then
    for i in \${SD_DIR_0} \${SD_DIR_1} \${SD_DIR_2} \${SD_DIR_3} \${SD_DIR_4} \${SD_DIR_5}; do
        if [[ -d \${i} ]];then
            TMOE_SD_DIR=\${i}
            break
        fi
    done
    [[ -z \${TMOE_SD_DIR} ]] || set -- "\${@}" "--bind" "\${TMOE_SD_DIR}:\${SD_MOUNT_POINT}"
fi
if [[ \${MOUNT_DOCKER_DIR} = true ]]; then
    [[ ! -e "\${TMOE_DOCKER_DIR}" ]] || set -- "\${@}" "--bind" "\${TMOE_DOCKER_DIR}"
fi
if [[ \${MOUNT_DEV_DRI} = true && -e \${DEV_DRI} ]]; then
    set -- "\${@}" "--bind" "\${DEV_DRI}"
fi
if [[ \${MOUNT_NVIDIA_GPU} = true && -e \${NVIDIA_GPU} ]]; then
    set -- "\${@}" "--bind" "\${NVIDIA_GPU}"
    [[ ! -e \${NVIDIA_CTL} ]] || set -- "\${@}" "--bind" "\${NVIDIA_CTL}"
fi
if [[ \${MOUNT_X11_UNIX} = true && -e \${X11_UNIX_DIR} ]]; then
    if [[ \${X11_UNIX_RO} = true ]];then
        MOUNT_ARG="bind-ro"
    else
        MOUNT_ARG="bind"
    fi
    set -- "\${@}" "--${MOUNT_ARG}" "\${X11_UNIX_DIR}"
fi
for ((i = 1; i <= \${NUM_OF_MOUNTS}; i++)); do
    MOUNT_SOURCE="MOUNT_SOURCE_\${i}"
    MOUNT_POINT="MOUNT_POINT_\${i}"
    if [[ -n "BIND_RO_\${i}" ]]; then
        BIND_RO="BIND_RO_\${i}"
        case \${!BIND_RO} in
        true) BIND_ARG="bind-ro" ;;
        *) BIND_ARG="bind" ;;
        esac
    else
        BIND_ARG="bind"
    fi
    if [[ -n \${!MOUNT_SOURCE} && -x \${!MOUNT_SOURCE} ]]; then
        set -- "\${@}" "--\${BIND_ARG}" "\${!MOUNT_SOURCE}:\${!MOUNT_POINT}"
    fi
done
#######################
if [[ -n \${CHROOT_BIN} ]]; then
    if [[ \${CHROOT_BIN} = system ]]; then
        set -- "systemd-nspawn" "\${@}"
    elif [[ \${CHROOT_BIN} = termux || \${CHROOT_BIN} = prefix ]]; then
        set -- "\${PREFIX}/bin/systemd-nspawn" "\${@}"
    else
        set -- "\${CHROOT_BIN}" "\${@}"
    fi
else
    set -- "systemd-nspawn" "\${@}"
fi
unset LD_PRELOAD
TMOE_NSPAWN_EXEC="exec \${@}"
su -c "\${TMOE_NSPAWN_EXEC}"
#exit 0
ENDOFTMOECHROOT

case $(uname -o) in
Android) termux-fix-shebang "${TMP_FILE}" ;;
esac
${TMOE_CHROOT_PREFIX} cp -f "${TMP_FILE}" "${TMOE_STARTUP_SCRIPT}"
${TMOE_CHROOT_PREFIX} mv -f "${TMP_FILE}" "${TMOE_STARTUP_DIR}"/nspawn
